package com.adam.springbucks.service.impl;

import com.adam.springbucks.aop.BucksException;
import com.adam.springbucks.aop.ResCode;
import com.adam.springbucks.unit.SnowflakeIdWorker;
import com.adam.springbucks.per.entity.Person;
import com.adam.springbucks.mapper.PersonMapper;
import com.adam.springbucks.service.PersonService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @ClassName: PersonServiceImpl
 * @Author Adam
 * @Date 2022/10/29
 * @Description: PersonServiceImpl 业务实现类继承 ServiceImpl 类生成增删改查基础业务方法
 */
@Service
@CacheConfig(cacheNames = {"person"})
public class PersonServiceImpl extends ServiceImpl<PersonMapper, Person> implements PersonService {

    @Resource
    private PersonServiceImpl personService;

    @Resource
    private PersonMapper personMapper;

    @Override
    @Transactional(rollbackFor = BucksException.class, propagation = Propagation.REQUIRED)
    public Person addPerson(Person person) {
        Person pExist = personMapper.findPersonByName(person.getName());
        if (!ObjectUtils.isEmpty(pExist)) {
            throw new BucksException(ResCode.BUC_DATA_FOUND);
        }
        long id = SnowflakeIdWorker.getInstance().generateId();
        person.setId(id);
        personMapper.insert(person);
        return person;
    }

    @Override
    public List<Person> findPersonByIds(List<Long> ids) {
        return personMapper.selectBatchIds(ids);
    }

    @Override
    @Cacheable(key = "#id", unless = "#id==null")
    public Person findPerson(Long id) {
        Person person = personService.getById(id);
        if (ObjectUtils.isEmpty(person)) {
            throw new BucksException(ResCode.BUC_DATA_NOT_FOUND);
        }
        return person;
    }


    @Override
    @CachePut(key = "#person.id", unless = "#person == null")
    @Transactional(rollbackFor = BucksException.class, propagation = Propagation.REQUIRED)
    public Person setPerson(Person person) {
        Person byId = personService.getById(person.getId());
        if (!ObjectUtils.isEmpty(byId)) {
            throw new BucksException(ResCode.BUC_DATA_NOT_FOUND);
        }
        personService.updateById(person);
        return person;
    }

    @Override
    @CacheEvict(key = "#id")
    @Transactional(rollbackFor = BucksException.class, propagation = Propagation.REQUIRED)
    public boolean deletePerson(Long id) {
        Person person = personService.getById(id);
        if (!ObjectUtils.isEmpty(person)) {
            throw new BucksException(ResCode.BUC_DATA_NOT_FOUND);
        }
        return personService.removeById(id);
    }

    @Override
    public IPage<Person> findPersonByPagination(Integer current, Integer size) {
        // 分页规则 search参数判断是否查询count 和 pages; 不查询适用于移动端下拉分页场景.
        Page<Person> personPage = new Page<>(current, size, true);
        // 条件构造器(无条件)
        LambdaQueryWrapper<Person> query = new LambdaQueryWrapper<Person>();
        return personMapper.selectPage(personPage, query);
    }

    @Override
    public IPage<Person> findPersonByNameOrAge(Page<Person> page, String name, Integer age) {
        return personMapper.findPersonByNameOrAge(page, name, age);
    }

    @Override
    public IPage<Person> findAllPerson(Page<Person> page, String condition) {
        LambdaQueryWrapper<Person> queryWrapper = Wrappers.<Person>lambdaQuery();
        if (condition.equalsIgnoreCase("0")) {
            queryWrapper.orderByDesc(Person::getScore);
        } else {
            queryWrapper.orderByAsc(Person::getScore);
        }
        return personMapper.selectPage(page, queryWrapper);
    }

    @Override
    public Person findPersonByName(String name) {
        Person person = personMapper.findPersonByName(name);
        if (ObjectUtils.isEmpty(person)) {
            throw new BucksException(ResCode.BUC_DATA_NOT_FOUND);
        }
        return person;
    }


}
